package com.revai.engine.basic.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import cn.hutool.json.JSONObject;

public class StrUtils {

    final static char[] RANDOM_CODES_SM = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
            'f' };

    final static char[] RANDOM_CODES_LG = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
            'V', 'W', 'X', 'Y', 'Z',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
            'v', 'w', 'x', 'y', 'z' };

    // 合并两个 JSON 对象的方法
    public static JSONObject MergeJSONObjects(JSONObject obj1, JSONObject obj2) {
        JSONObject mergedObj = new JSONObject();
        // 将 obj1 中的所有键值对放入 mergedObj
        mergedObj.putAll(obj1);
        for (String key : obj2.keySet()) {
            // 如果 mergedObj 中已经存在相同的键，则使用 obj2 中的值覆盖 mergedObj 中的值
            if (mergedObj.containsKey(key)) {
                mergedObj.put(key, obj2.get(key));
            } else {
                // 如果 mergedObj 中不存在相同的键，则将 obj2 中的键值对放入 mergedObj
                mergedObj.put(key, obj2.get(key));
            }
        }
        return mergedObj;
    }

    /**
     * 生成随机a-f+数字的随机字符串
     *
     * @param length
     * @return
     */
    public static String getRandomString(int length) {
        int charLength = RANDOM_CODES_SM.length;
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append(RANDOM_CODES_SM[random.nextInt(charLength)]);
        }
        return sb.toString();
    }

    /**
     * 生成26大小写字母+数字的随机字符串
     *
     * @param length
     * @return
     */
    public static String getRandomStringCase(int length) {
        int charLength = RANDOM_CODES_LG.length;
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append(RANDOM_CODES_LG[random.nextInt(charLength)]);
        }
        return sb.toString();
    }

    /**
     * sha1加密
     *
     * @param text
     * @return
     */
    public static String sha1(String text) {
        MessageDigest md = null;
        String outStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(text.getBytes());
            outStr = toHex(digest);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return outStr;
    }

    /**
     * md5加密
     * 
     * @param s
     * @return
     */
    public static String md5(String s) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(s.getBytes("utf-8"));
            return toHex(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * inputStream转字符串
     * 
     * @param inputStream
     * @return
     */
    public static String inputStream2String(InputStream inputStream) {
        String str = "";
        try {
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            str = result.toString(StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 字节数组转字符串
     *
     * @param digest
     * @return
     */
    private static String toHex(byte[] digest) {
        StringBuilder buf = new StringBuilder();
        for (int i = 0; i < digest.length; i++) {
            String tempStr = Integer.toHexString(digest[i] & 0xff);
            if (tempStr.length() == 1) {
                buf.append("0").append(tempStr);
            } else {
                buf.append(tempStr);
            }
        }
        return buf.toString().toLowerCase();
    }

    /**
     * 返回表名 ./table/User.yaml -> user
     * 
     * @param str
     * @return
     */
    public static String getTableName(String str) {
        //以'/'划分数组字符串
        String[] strs = str.split("/");
        //获取数组中最后一个文件名全称
        String fileName = strs[strs.length - 1];
        //转义以 . 分割,获取第0位数组字符串，转换为小写
        return fileName.split("\\.")[0].toLowerCase();
    }

    /**
     * 返回表名 ./table/User.yaml -> User
     * 
     * @param str
     * @return
     */
    public static String getMedelName(String str) {
        //同上述代码，不过最后不转换为小写
        String[] strs = str.split("/");
        String fileName = strs[strs.length - 1];
        return fileName.split("\\.")[0];
    }

    /**
     * 返回表id ./table/User.yaml -> tableUseryaml
     * 
     * @param str
     * @return
     */
    public static String getTablePath(String str) {
        return str.replaceAll("\\.", "").replaceAll("\\/", "");
    }

    /**
     * 字符串转驼峰
     * 
     * @param input
     * @return
     */
    public static String toClassCamelCase(String input) {
        StringBuilder result = new StringBuilder();

        // 标记当前字符是否需要大写转换
        boolean capitalizeNext = false;

        for (int i = 0; i < input.length(); i++) {
            char currentChar = input.charAt(i);

            if (currentChar == '_' || currentChar == '-') {
                // 下一个字符需要大写转换
                capitalizeNext = true;
            } else {
                // 根据标记决定是否进行大写转换
                result.append(capitalizeNext || i == 0 ? Character.toUpperCase(currentChar) : currentChar);
                capitalizeNext = false;
            }
        }

        return result.toString();
    }

    /**
     * 属性名字符串转驼峰（暂时只首字母大些）
     * 
     * @param input
     * @return
     */
    public static String toFieldCamelCase(String input) {
        return input.substring(0, 1).toUpperCase() + input.substring(1);
    }
}
